﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Excel;
using Microsoft.AspNetCore.JsonPatch.Operations;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json.Linq;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.CG;
using NP.BPMReportPlatform.CG.Dto;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Business.LCZX;
using NP.BPMReportPlatform.Entities.BPM_Engine;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.HR.Dto;
using NP.BPMReportPlatform.MaterialMasterData;
using NP.BPMReportPlatform.MaterialMasterData.Dto;
using NP.BPMReportPlatform.Utilities;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using NPOI.SS.Formula.Functions;
using SqlSugar;
using Volo.Abp.Application.Dtos;

namespace NP.BPMReportPlatform.FrameOrder
{
    public class LCZXCPGJService : BPMReportPlatformAppService, ILCZXCPGJService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly SqlSugarClient _dbEngine;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly INPRestHttpHelper _nPRestHttp;
        private readonly IExcelImporter _importer;

        public LCZXCPGJService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, INPRestHttpHelper nPRestHttp, IConfiguration configuration, IExcelImporter importer)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _nPRestHttp = nPRestHttp;
            _importer = importer;
        }

        public async Task<PagedResultDto<LCZXCPGJOutput>> GetAllAsync(LCZXCPGJInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);
            listViewDto.ForEach(x =>
            {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
            });

            //返回结果
            return new PagedResultDto<LCZXCPGJOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<LCZXCPGJOutput>> ExportAsync(LCZXCPGJInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }

        /// <summary>
        /// 获取Queryable(报表展现)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private ISugarQueryable<LCZXCPGJOutput> GetQueryable(LCZXCPGJInput input)
        {
            var listQueryable = _db.Queryable<LCZXCPGJHeader, BusinessProcessesNew, LBDXListingApplicationDetail>(
                (x, m, d) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == m.InstanceId,
                JoinType.Left, x.CourseId.Equals(d.Id)))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, m) => x.InstanceNumber.Contains(input.InstanceNumber))
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, m) => SqlFunc.ContainsArray(input.OrderStatus.ToArray(), m.ProcessStatusCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, m) => m.StartUserName.Equals(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.AddTime >= input.StartCreationTime && x.AddTime.AddDays(-1) <= input.EndCreationTime)
                .Select((x, m, d) => new LCZXCPGJOutput()
                {
                    InstanceNumber = x.InstanceNumber,
                    CreateTime = x.AddTime,
                    CreateTimeStr = x.AddTime.ToString(DateFormatHelper.DateTimeFormat),
                    OrderStatus = m.ProcessStatusName,
                    AddUserName = m.StartUserName,
                    CourseCode = x.CourseCode,
                    CourseName = d.ProductName,
                    ChangeReason = x.ChangeReason,
                    ValidStartTime = x.ValidStartTime,
                    ValidStartTimeStr = x.ValidStartTime == null ? "" : x.ValidStartTime.Value.ToString(DateFormatHelper.DateFormat),
                    ValidEndTime = x.ValidEndTime,
                    ValidEndTimeStr = x.ValidEndTime == null ? "" : x.ValidEndTime.Value.ToString(DateFormatHelper.DateFormat),
                    Price = x.Price,
                    Unit = x.Unit,
                    PeopleCount = x.PeopleCount,
                    TotalPrice = x.TotalPrice,
                    TotalCost = x.TotalCost,
                    ClassCount = x.ClassCount,
                    Profit = x.Profit,
                    RMCC = x.RMCC,
                    BeforePrice = x.BeforePrice,
                    BeforeUnit = x.BeforeUnit,
                    BeforeTotalPrice = x.BeforeTotalPrice,
                    BeforeTotalCost = x.BeforeTotalCost,
                    BeforeProfit = x.BeforeProfit,
                    BeforeRMCC = x.BeforeRMCC,
                    BeforeStartDate = x.BeforeStartDate,
                    BeforeStartDateStr = x.BeforeStartDate == null ? "" : x.BeforeStartDate.Value.ToString(DateFormatHelper.DateFormat),
                    BeforeEndDate = x.BeforeEndDate,
                    BeforeEndDateStr = x.BeforeEndDate == null ? "" : x.BeforeEndDate.Value.ToString(DateFormatHelper.DateFormat),
                    AsyncTime = x.AsyncTime,
                    AsyncTimeStr = x.AsyncTime == null ? "" : x.AsyncTime.Value.ToString(DateFormatHelper.DateTimeFormat),
                    IsSyncSuccess = x.IsSyncSuccess,
                    SyncSuccess = x.IsSyncSuccess == 1 ? "是" : "否",
                    SyncResult = x.SyncResult,
                }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc);
            return listQueryable;
        }
    }
}